﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ionic.Zip;
using System.IO;
using System.Text.RegularExpressions;

namespace CreateMultiProjectTemplate
{
    class Program
    {
        public static List<string> ListOfFile = new List<string>();

        static void Main(string[] args)
        {

            DirectoryInfo destination = new DirectoryInfo(@"C:\Codeplex\NeosSDIMVC4\Deploy\NeosSDI.MVC4.ProjectTemplate\C");
            foreach (var item in destination.GetDirectories())
            {
                Directory.Delete(item.FullName, true);
            }

            DirectoryInfo dir = new DirectoryInfo(@"C:\Users\jean-francois\Documents\Visual Studio 2010\My Exported Templates");
            foreach (var item in dir.GetFiles())
            {
                ListOfFile.Add(item.Name.Replace(item.Extension, ""));
            }
            foreach(var item in dir.GetFiles())
            {
                Unzip(item.FullName);
            }


            foreach (var item in dir.GetDirectories())
            {
                string _newName = item.Name.Split('.')[item.Name.Split('.').Length - 1];
                item.MoveTo(Path.Combine(item.Parent.FullName, destination.FullName+"\\"+_newName));
            }

            Console.WriteLine("Count Fixed Files: " + countFixedFile);
            Console.WriteLine("Count Non Fixed Files: " + countNonFixedFile);
        }

        private static void EditProjectFile(string filePath)
        {
            string toRemove = "<Compile Include=\"C\\";

            StreamReader reader = new StreamReader(filePath);
            string line = string.Empty;
            StringBuilder newFile = new StringBuilder();
            while ((line = reader.ReadLine()) != null)
            {
                if (!line.Contains(toRemove))
                {
                    newFile.AppendLine(line);
                }
            }

            StreamWriter writer = new StreamWriter(filePath);
            writer.Write(newFile.ToString());
            writer.Close();

            ParseDirectoryCsProj(new DirectoryInfo(new DirectoryInfo(filePath).FullName + "\\UI"));

        }

        public static List<string> FileToAddToProject = new List<string>();

        private static void ParseDirectoryCsProj(DirectoryInfo dir)
        {
            foreach (var item in dir.GetFiles())
            {
                FileToAddToProject.Add(item.FullName);
            }
            foreach (var item in dir.GetDirectories())
            {
                ParseDirectoryCsProj(item);
            }
        }

        private static void Unzip(string fileName)
        {
            using (ZipFile zip = new ZipFile(fileName))
            {
                FileInfo fi = new FileInfo(fileName);
                zip.ExtractAll(fi.FullName.Replace(fi.Extension, ""), ExtractExistingFileAction.OverwriteSilently);
                FixProject(fi.FullName.Replace(fi.Extension, ""), fi.Name.Replace(fi.Extension, ""));
                if (fi.FullName.Replace(fi.Extension, "").Contains("NeosSDI.MVC4.Web"))
                {
                    FixFolder(fi.FullName.Replace(fi.Extension, ""), fi.Name.Replace(fi.Extension, ""));
                }
            }
        }

        private static void FixProject(string project, string projectName)
        {
            DirectoryInfo dir = new DirectoryInfo(project);
            ParseDirectory(dir, projectName);
        }

        private static void FixFolder(string project, string projectName)
        {
            DirectoryInfo dir = new DirectoryInfo(project);
            RenameFolder(dir);
            ParseFixFolderDirectory(dir, projectName);
        }

        private static void ParseDirectory(DirectoryInfo dir, string projectName)
        {
            foreach (var item in dir.GetFiles())
            {
                FixFile(item, projectName);
            }
            foreach (var item in dir.GetDirectories())
            {
                ParseDirectory(item, projectName);
            }
        }

        private static void ParseFixFolderDirectory(DirectoryInfo dir, string projectName)
        {
            foreach (var item in dir.GetFiles())
            {
                if (item.Extension == ".vstemplate")
                {
                    FixFileFolder(item, projectName);
                }
            }
            foreach (var item in dir.GetDirectories())
            {
                ParseFixFolderDirectory(item, projectName);
            }
        }
        private static void FixFileFolder(FileInfo item, string projectName)
        {
            //string pattern = "Name=\"{0}\" TargetFolderName=";

            //ReplaceInFile(item.FullName, string.Format(pattern, "images"), string.Format(pattern, "i"));
            //ReplaceInFile(item.FullName, string.Format(pattern, "treeview"), string.Format(pattern, "t"));
            //ReplaceInFile(item.FullName, string.Format(pattern, "default"), string.Format(pattern, "d"));
            //ReplaceInFile(item.FullName, string.Format(pattern, "base"), string.Format(pattern, "b"));
            //ReplaceInFile(item.FullName, string.Format(pattern, "themes"), string.Format(pattern, "t"));
            //ReplaceInFile(item.FullName, string.Format(pattern, "ExternalLibrary"), string.Format(pattern, "EL"));
            //ReplaceInFile(item.FullName, string.Format(pattern, "JqueryCore"), string.Format(pattern, "JC"));
            //ReplaceInFile(item.FullName, string.Format(pattern, "Page"), string.Format(pattern, "p"));
            //ReplaceInFile(item.FullName, string.Format(pattern, "Scripts"), string.Format(pattern, "s"));
            //ReplaceInFile(item.FullName, string.Format(pattern, "Content"), string.Format(pattern, "c"));

            ////replace ReplaceParameters="false" by ReplaceParameters="true" for cshtml files
            //ReplaceInFileByLine(item.FullName, "ReplaceParameters=\"false\"", "ReplaceParameters=\"true\"", ".cshtml");
        }
        private static void RenameFolder(DirectoryInfo dir)
        {
            
        //    RenameFolder(dir + "\\Areas\\CustomAdministration", dir + "\\Areas\\ca");
        //    RenameFolder(dir + "\\Content\\themes\\base\\minified\\images", dir + "\\Content\\themes\\base\\minified\\i");
        //    RenameFolder(dir + "\\Content\\themes\\base\\minified", dir + "\\Content\\themes\\base\\m");
        //    RenameFolder(dir + "\\Content\\themes\\base\\images", dir + "\\Content\\themes\\base\\i");
        //    RenameFolder(dir + "\\Content\\themes\\default\\images\\treeview", dir + "\\Content\\themes\\default\\images\\t");
        //    RenameFolder(dir + "\\Content\\themes\\default\\images", dir + "\\Content\\themes\\default\\i");
        //    RenameFolder(dir + "\\Content\\themes\\default", dir + "\\Content\\themes\\d");
        //    RenameFolder(dir + "\\Content\\themes\\base", dir + "\\Content\\themes\\b");
        //    RenameFolder(dir + "\\Content\\themes", dir + "\\Content\\t");
        //    RenameFolder(dir + "\\Content", dir + "\\c");
        //    RenameFolder(dir + "\\Scripts\\ExternalLibrary", dir + "\\Scripts\\EL");
        //    RenameFolder(dir + "\\Scripts\\JqueryCore", dir + "\\Scripts\\JC");
        //    RenameFolder(dir + "\\Scripts\\Page", dir + "\\Scripts\\P");
        //    RenameFolder(dir + "\\Scripts", dir + "\\S");
        }

        private static void RenameFolder(string source, string target)
        {
            if (Directory.Exists(target))
                Directory.Delete(target, true);
            if (Directory.Exists(source))
                Directory.Move(source, target);
        }


        public static long countFixedFile = 0;
        public static long countNonFixedFile = 0;

        private static void FixFile(FileInfo item, string projectName)
        {
            if (item.Extension == ".dll" || item.Extension == ".jpg" || item.Extension == ".ico" || item.Extension == ".gif" || item.Extension == ".png")
                return;
            bool result = false;

            if (item.Extension.Contains("vstemplate"))
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("<WizardExtension>");
                sb.AppendLine("  <Assembly>NeosSDI.ProjectTemplateWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=83c923a433606a70</Assembly>");
                sb.AppendLine("  <FullClassName>NeosSDI.ProjectTemplateWizard.IWizardImplementationChild</FullClassName>");
                sb.AppendLine("</WizardExtension>");
                sb.AppendLine("</VSTemplate>");
                ReplaceInFile(item.FullName, "</VSTemplate>", sb.ToString());
            }

            foreach (var prjName in ListOfFile)
            {
                var _array = prjName.Split('.');
                string _lastPart = _array[_array.Length - 1];
                if (ReplaceInFile(item.FullName, prjName, "$solutionNameChild$." + _lastPart))
                    result = true;
                if (ReplaceInFile(item.FullName, prjName, "$solutionNameChild$." + _lastPart))
                    result = true;
            }

            if (ReplaceInFile(item.FullName, projectName, "$safeprojectname$"))
                result = true;
            if (ReplaceInFile(item.FullName, projectName, "$safeprojectname$"))
                result = true;
            if (item.FullName.Contains("vstemplate"))
            {
                if (ReplaceInFileByLine(item.FullName, "ReplaceParameters=\"false\"", "ReplaceParameters=\"true\"", ".cshtml"))
                    result = true;
            }
            if (ReplaceInFile(item.FullName, @"..\..\..\..\packages\", @"..\..\..\packages\"))
                result = true;
            if (item.Extension.ToLower().Contains("vstemplate"))
            {
                var _array = projectName.Split('.');
                string _lastPart1 = _array[_array.Length - 1];
                ReplaceInFile(item.FullName, "File=\"$solutionNameChild$", "File=\"" + projectName.Replace("." + _lastPart1, ""));

                ReplaceInFile(item.FullName, "TargetFileName=\"$solutionNameChild$.Project.csproj\"", "TargetFileName=\"$solutionNameChild$.Web.csproj\"");
                
            }
            if (item.Extension.ToLower().Contains("csproj"))
            {
                ReplaceInFile(item.FullName, @"..\$solutionNameChild$.DAL.ADO\$solutionNameChild$.DAL.ADO.csproj", @"..\..\3.DAL\$solutionNameChild$.DAL\$solutionNameChild$.DAL.ADO.csproj");
                ReplaceInFile(item.FullName, @"..\$solutionNameChild$.DAL.EF\$solutionNameChild$.DAL.EF.csproj", @"..\..\3.DAL\$solutionNameChild$.DAL\$solutionNameChild$.DAL.EF.csproj");
                ReplaceInFile(item.FullName, @"..\$solutionNameChild$.Services\$solutionNameChild$.Services.csproj" , @"..\..\2.Services\$solutionNameChild$.Services\$solutionNameChild$.Services.csproj");
                ReplaceInFile(item.FullName, @"..\$solutionNameChild$.Transverse\$solutionNameChild$.Transverse.csproj", @"..\..\4.Transverse\$solutionNameChild$.Transverse\$solutionNameChild$.Transverse.csproj");
                ReplaceInFile(item.FullName, @"..\$solutionNameChild$.Web\$solutionNameChild$.Web.csproj", @"..\..\1.Web\$solutionNameChild$.Web\$solutionNameChild$.Web.csproj");
            }
            if (result)
                countFixedFile++;
            else
                countNonFixedFile++;
        }

        /// Replaces text in a file.
        /// </summary>
        /// <param name="filePath">Path of the text file.</param>
        /// <param name="searchText">Text to search for.</param>
        /// <param name="replaceText">Text to replace the search text.</param>
        static public bool ReplaceInFile(string filePath, string searchText, string replaceText)
        {
            StreamReader reader = new StreamReader(filePath);
            string content = reader.ReadToEnd();
            reader.Close();
            bool result = false;
            if (content.Contains(searchText))
                result = true;
            content = content.Replace(searchText, replaceText);

            StreamWriter writer = new StreamWriter(filePath);
            writer.Write(content);
            writer.Close();
            return result;
        }
        /// Replaces text in a file.
        /// </summary>
        /// <param name="filePath">Path of the text file.</param>
        /// <param name="searchText">Text to search for.</param>
        /// <param name="replaceText">Text to replace the search text.</param>
        static public bool ReplaceInFileByLine(string filePath, string searchText, string replaceText, string pattern)
        {
            StreamReader reader = new StreamReader(filePath);
            StringBuilder sb = new StringBuilder();
            string line = "";
            string[] _array = pattern.Split('|');
            while ((line = reader.ReadLine()) != null)
            {
                foreach (var item in _array)
                {
                    if (line.Contains(item))
                    {
                        line = line.Replace(searchText, replaceText);
                        break;
                    }
                }
                sb.AppendLine(line);
            }
            reader.Close();

            StreamWriter writer = new StreamWriter(filePath);
            writer.Write(sb.ToString());
            writer.Close();
            return true;
        }
    }
}
